home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Inspectors / WrapperInspector / WrapperInspector.m < prev   
Text File  |  1995-06-12  |  9KB  |  342 lines

  1. //----------------------------------------------------------------------------------------------------
  2. //
  3. //    WrapperInspector
  4. //
  5. //    Inherits From:        Object
  6. //
  7. //    Declared In:        WrapperInspector.h
  8. //
  9. //    Disclaimer
  10. //
  11. //        You may freely copy, distribute and reuse this software and its
  12. //        associated documentation. I disclaim any warranty of any kind, 
  13. //        expressed or implied, as to its fitness for any particular use.
  14. //
  15. //----------------------------------------------------------------------------------------------------
  16. #import "WrapperInspector.h"
  17. #import "DefaultSubInspector.h"
  18. #import <objc/objc-runtime.h>
  19. #import <bsd/sys/dir.h>
  20.  
  21.  
  22. @implementation WrapperInspector
  23.  
  24. static id     _SELF = nil;
  25.  
  26. //----------------------------------------------------------------------------------------------------
  27. //  WMInspector Methods
  28. //----------------------------------------------------------------------------------------------------
  29. + new
  30. {
  31.     //  Required/called by WM.  Only allow one instance...
  32.     
  33.         char     path[MAXPATHLEN+1];
  34.         id         bundle;
  35.  
  36.         if (_SELF) return _SELF;
  37.  
  38.         _SELF = self = [super new];
  39.  
  40.         if ( ! (bundle = [NXBundle bundleForClass: [WrapperInspector class]] ) ) return nil;          
  41.     if ( ! [bundle getPath: path forResource: "WrapperInspector" ofType: "nib"] ) return nil;
  42.         [NXApp loadNibFile: path owner: self  withNames: NO fromZone: [self zone]];
  43.  
  44.      [splitView addSubview: browser];
  45.     [splitView addSubview: inspectorView];
  46.     [splitView adjustSubviews];
  47.     [splitView display];
  48.     
  49.      return _SELF;
  50. }
  51.  
  52.  
  53. - revert: sender
  54. {
  55.     //  Called by WM when file selection is type we inspect or when 
  56.     //  'Open As Folder' button is pressed.
  57.     
  58.     if (sender == [self revertButton])
  59.         {
  60.         [self openAsFolder: nil];
  61.         return [super revert:sender];
  62.         }
  63.  
  64.     [[[[self okButton] setTitle: "Open"] setIconPosition: NX_TITLEONLY] setEnabled: YES];
  65.     [[[self revertButton] setTitle: "Open As Folder"] setEnabled: YES];
  66.  
  67.     [browser setDoubleAction: @selector(open:)];
  68.     [browser setTitle: [fileNameField stringValue] ofColumn: 0];
  69.     [browser loadColumnZero];
  70.     
  71.     if ([self isDirectory])
  72.         [self noInspector];
  73.     else
  74.         [self selectionNotADirectory];
  75.     
  76.     [self updateSubPath];
  77.  
  78.     [super revert: sender];
  79.     return self;
  80. }
  81.  
  82.  
  83. - ok: sender
  84. {
  85.     //  User pressed 'Open' button...
  86.     
  87.     [self open: nil];
  88.     return [super ok:sender];
  89. }
  90.  
  91.  
  92. //----------------------------------------------------------------------------------------------------
  93. //  Action Methods
  94. //----------------------------------------------------------------------------------------------------
  95. - fileSelected: sender
  96. {
  97.     //  Invoke inpector based on extension... Enable 'Open As Folder'
  98.     //  button if directory.  Update subPath display.
  99.     
  100.     STR            currentPath;
  101.     STR            extension;
  102.     const char*    inspectorClass;    
  103.  
  104.     [self updateSubPath];
  105.  
  106.     if (! (currentPath = [self currentPath])) return [self noInspector];
  107.     
  108.     if ([[browser selectedCell] isLeaf]) 
  109.         [[self revertButton] setEnabled: NO];
  110.     else
  111.         [[self revertButton] setEnabled: YES];
  112.         
  113.     if (! (extension = [self extension: currentPath]))
  114.         {
  115.         if (currentPath) free(currentPath);
  116.         return [self noInspector];
  117.         }
  118.  
  119.     if ((inspectorClass = [inspectorStrings valueForStringKey: extension]))
  120.         [self inspect: (STR)currentPath usingInspectorClass: (STR)inspectorClass];
  121.     else
  122.         [self noInspector];
  123.  
  124.     if (currentPath) free(currentPath);
  125.     if (extension) free(extension);
  126.     
  127.     return self;
  128. }
  129.  
  130.  
  131. - open: sender
  132. {
  133.     //  Open current selection in WM.
  134.  
  135.     STR    currentPath;
  136.     int    openStatus;
  137.     id    appListener = NXResponsibleDelegate ([NXApp appListener], @selector(openFile:ok:));
  138.     
  139.     if (! (currentPath = [self currentPath])) return NULL;
  140.     [appListener openFile: currentPath ok: &openStatus];
  141.     if (currentPath) free(currentPath);
  142.     return self;
  143. }
  144.     
  145.     
  146. - openAsFolder: sender
  147. {
  148.     //  Open current selection as folder in WM.
  149.  
  150.     STR        currentPath;
  151.     
  152.     if (! (currentPath = [self currentPath])) return NULL;
  153.     [[Application workspace] selectFile:currentPath inFileViewerRootedAt:currentPath];
  154.     if (currentPath) free(currentPath);
  155.     return self;
  156. }
  157.     
  158.     
  159. //----------------------------------------------------------------------------------------------------
  160. //  Inspection Methods
  161. //----------------------------------------------------------------------------------------------------
  162. - inspect: (STR)currentPath usingInspectorClass: (STR)inspectorClass
  163. {
  164.     //  Get the Class ID for the specified subinspector and send it the
  165.     //  message 'new' to create an instance.  If successful, message 
  166.     //  the instance for its inspectorView and to inspect the current path.
  167.     
  168.     id        inspector;
  169.     Class      inspectorClassID = objc_lookUpClass(inspectorClass);
  170.     
  171.     if ( ! inspectorClassID)  return [self noInspector];
  172.     
  173.     inspector = objc_msgSend ((id)inspectorClassID, @selector(new));
  174.     if ( ! inspector)  return [self noInspector];
  175.  
  176.     [inspectorView setContentView: [inspector inspectorView]];
  177.     [inspectorView display];
  178.     
  179.     [inspector inspect: currentPath];
  180.     
  181.     return self;
  182. }
  183.     
  184.  
  185. - noInspector
  186. {
  187.     //  No Inspector for this file type.
  188.     
  189.     [messageText setStringValue: "No Inspector"];
  190.     [inspectorView setContentView: [messageView contentView]];
  191.     [inspectorView display];
  192.     return self;
  193. }
  194.  
  195.  
  196. - selectionNotADirectory
  197. {
  198.     //  This for cases when WM selection has right extension, but is not
  199.     //  actually a directory (for example, some .nibs are not directories).
  200.     
  201.     [[self okButton] setEnabled: NO];
  202.     [[self revertButton] setEnabled: NO];
  203.     [messageText setStringValue: "Not A Directory"];
  204.     [inspectorView setContentView: [messageView contentView]];
  205.     [inspectorView display];
  206.     return self;
  207. }
  208.  
  209.  
  210. //----------------------------------------------------------------------------------------------------
  211. //  Selection Path Methods
  212. //----------------------------------------------------------------------------------------------------
  213. - (STR) currentPath
  214. {
  215.     //  Original WM selection path plus current browser path.  Caller must free.
  216.     
  217.     char     currentPath[MAXPATHLEN+1];
  218.     char     browserPath[MAXPATHLEN+1];
  219.  
  220.     [self selectionPathsInto:currentPath separator:'\0'];
  221.     
  222.     if ([browser selectedCell])
  223.         {
  224.         [browser getPath:browserPath toColumn: [browser selectedColumn]];
  225.         strcat (currentPath, browserPath);
  226.         strcat (currentPath, "/");
  227.         strcat (currentPath, [[browser selectedCell] stringValue]);
  228.         }
  229.     
  230.     return NXCopyStringBuffer (currentPath);
  231. }
  232.  
  233.  
  234. - (STR) extension: (const char*) path
  235. {
  236.     //  File's extension if found, pointer to NULL otherwise.  Caller must free.
  237.  
  238.     STR    start = (STR)path;
  239.     STR    end;
  240.  
  241.     for (end = (start + strlen(start) -1); end >= start; end--)
  242.         {
  243.         if (*end == '.') break;
  244.         if (*end == '/') return NULL;
  245.         }
  246.  
  247.     if ((end - start) == -1) return NULL;
  248.         
  249.     start += (end - start) + 1;
  250.     return NXCopyStringBuffer(start);
  251. }
  252.  
  253.  
  254. - (BOOL)isDirectory
  255. {
  256.     //  YES if current path is a directory...
  257.     
  258.     struct stat     statBuffer;
  259.     STR            currentPath = [self currentPath];
  260.  
  261.     if (! currentPath) return NO;
  262.     
  263.     stat (currentPath, &statBuffer); 
  264.     if (currentPath) free(currentPath);
  265.     if ( (statBuffer.st_mode & S_IFMT) != S_IFDIR)
  266.         return NO;
  267.         
  268.     return YES;
  269. }
  270.  
  271.  
  272. - updateSubPath
  273. {
  274.     //  Update subPath display...
  275.     
  276.     char     subPath[MAXPATHLEN+1];
  277.     char     browserPath[MAXPATHLEN+1];
  278.  
  279.     strcpy(subPath, [fileNameField stringValue]);
  280.  
  281.     if ([browser selectedCell])
  282.         {
  283.         [browser getPath:browserPath toColumn: [browser selectedColumn]];
  284.         strcat (subPath, browserPath);
  285.         strcat (subPath, "/");
  286.         strcat (subPath, [[browser selectedCell] stringValue]);
  287.         }
  288.  
  289.     [subPathText setStringValue: subPath];
  290.     return self;
  291. }
  292.  
  293.  
  294. //----------------------------------------------------------------------------------------------------
  295. //  Browser Delegate Method
  296. //----------------------------------------------------------------------------------------------------
  297. - (int) browser: aBrowser fillMatrix: aMatrix inColumn: (int)aColumn
  298. {
  299.     int            count = 0;
  300.     DIR*            directory;
  301.     STR         currentPath;
  302.     char         pathBuffer[MAXPATHLEN+1];
  303.     struct stat     statBuffer;
  304.     struct direct*    directoryPointer;
  305.  
  306.     currentPath = [self currentPath];
  307.         
  308.     if (! (directory = opendir(currentPath))) 
  309.         {
  310.         if (currentPath)  free(currentPath);
  311.         [self selectionNotADirectory];
  312.         return 0;
  313.         }
  314.     
  315.     for (directoryPointer = readdir(directory); directoryPointer != NULL; 
  316.             directoryPointer =  readdir(directory))
  317.         {
  318.         if (NXOrderStrings (directoryPointer->d_name, ".", YES, -1, NULL) == 0) continue;
  319.         if (NXOrderStrings (directoryPointer->d_name, "..", YES, -1, NULL) == 0) continue;
  320.  
  321.         [aMatrix renewRows: (count+1) cols: 1];
  322.         [[aMatrix cellAt: count :0] setStringValue: directoryPointer->d_name];
  323.         [[aMatrix cellAt: count :0] setLoaded: YES];
  324.         
  325.         strcpy (pathBuffer, currentPath);
  326.         strcat (pathBuffer, "/");
  327.         strcat (pathBuffer, directoryPointer->d_name);
  328.  
  329.         stat (pathBuffer, &statBuffer); 
  330.         if ( (statBuffer.st_mode & S_IFMT) != S_IFDIR)
  331.                 [[aMatrix cellAt: count :0] setLeaf:YES];
  332.             
  333.         count++;
  334.         }
  335.     
  336.     if (currentPath)  free(currentPath);
  337.     closedir(directory);
  338.     return count;
  339. }
  340.     
  341.  
  342. @end